package com.constant;

import java.util.HashMap;
import java.util.Map;

/**
 * 各功能码
 * @author zhujh
 */
public enum FuncitonCodeEnum {
    READ_COILS(0x1),
    READ_DISCRETE_INPUTS(0x2),
    READ_HOLDING_REGISTERS(0x3),
    READ_INPUT_REGISTERS(0x4),
    WRITE_SINGLE_COIL(0x5),
    WRITE_SINGLE_REGISTER(0x6),
//    READ_EXCEPTION_STATUS(0x7),//serial line only
//    DIAGNOSTICS(0x8),//serial line only
//    GET_COMM_EVENT_COUNTER(0x0B),//serial line only
//    GET_COMM_EVENT_LOG(0x0C),//serial line only
    WRITE_MULTIPLE_COILS(0x0F),
    WRITE_MULTIPLE_REGISTERS(0x10),
//    REPORT_SLAVE_ID(0x11),//serial line only
//    READ_FILE_RECORD(0x14),
//    WRITE_FILE_RECORD(0x15),
//    MASK_WRITE_REGISTER(0x16),
//    READ_WRITE_MULTIPLE_REGISTERS(0x17),
//    READ_FIFO_QUEUE(0x18),
//    ENCAPSULATED_INTERFACE_TRANSPORT(0x2B),

    UNKNOWN(0xff);

    final static private int MODBUS_EXCEPTION_FLAG = 0x80;

    final static private Map<Integer, FuncitonCodeEnum> values = new HashMap<Integer, FuncitonCodeEnum>(FuncitonCodeEnum.values().length);

    static {
        for (FuncitonCodeEnum func : FuncitonCodeEnum.values()) {
            values.put(func.value, func);
        }
    }

    final private int value;

    FuncitonCodeEnum(int value) {
        this.value = value;
    }

    static public FuncitonCodeEnum get(int value) {
        if (isException(value)) {
            value &= ~MODBUS_EXCEPTION_FLAG;
        }

        if (values.containsKey(value)) {
            return values.get(value);
        }
        return UNKNOWN;
    }

    static public boolean isException(int value) {
        return (value & MODBUS_EXCEPTION_FLAG) != 0;
    }

    static public int getExceptionValue(int functionCode) {
        return functionCode | MODBUS_EXCEPTION_FLAG;
    }

    public int toInt() {
        return value;
    }

    @Override
    public String toString() {
        return String.valueOf(value);
    }
}
